#include <iostream>
#include <vector>
#include <string>
#include <ctime>
#include <map>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <random>
#include <chrono>
#include <iomanip>
#include <limits>
#include <windows.h>

using namespace std;

// 运势数据库
struct LuckDatabase {
    vector<string> love;
    vector<string> career;
    vector<string> health;
    vector<string> wealth;
};

// 每日运势结果
struct DailyLuck {
    string date;
    string overallType;
    string overallDesc;
    map<string, string> details;
    int colorCode;
};

// 用户数据
struct UserData {
    string userId;
    vector<DailyLuck> history;
    string lastDrawDate;
};

namespace ConsoleColor {
    const int RED = 31;
    const int YELLOW = 33;
    const int GREEN = 32;
    const int GRAY = 37;
    const int BLACK = 30;
    const int DEFAULT = 0;
}

class LuckDrawSystem {
private:
    LuckDatabase db;
    UserData user;
    mt19937 rng;
    
    void initDatabase() {
        db.love = {
            "今日桃花运旺盛，可能会遇到心仪对象",
            "感情平稳，适合与伴侣深入交流",
            "小心沟通误会，避免情绪化决策"
        };
        
        db.career = {
            "工作上有突破机会，大胆展示你的想法",
            "按部就班完成任务即可，不宜冒险",
            "可能遇到挑战，但也是证明自己的机会"
        };
        
        db.health = {
            "精力充沛，适合开始新的健身计划",
            "注意劳逸结合，避免过度劳累",
            "关注睡眠质量，适当放松心情"
        };
        
        db.wealth = {
            "有意外之财机会，但需谨慎决策",
            "财务稳定，适合做长期规划",
            "避免冲动消费，注意收支平衡"
        };
    }
    
    int weightedRandom(const vector<double>& weights) {
        discrete_distribution<int> dist(weights.begin(), weights.end());
        return dist(rng);
    }
    
    string generateOverallDesc(const string& type) const {
        static map<string, string> descMap = {
            {"大吉", "今日万事顺遂，贵人相助，是行动的好时机！"},
            {"中吉", "平稳中有小惊喜，保持积极态度会有收获。"},
            {"小吉", "普通的一天，小小的努力也会带来回报。"},
            {"平", "平凡是福，享受当下的宁静时光吧。"},
            {"凶", "今日运势较低，谨慎行事，避免冲动决策。"}
        };
        return descMap.at(type);
    }
    
    string getCurrentDate() const {
        auto now = chrono::system_clock::now();
        time_t now_time = chrono::system_clock::to_time_t(now);
        tm* now_tm = localtime(&now_time);
        
        stringstream ss;
        ss << put_time(now_tm, "%Y-%m-%d %H:%M:%S");
        return ss.str();
    }
    
    string getTodayDate() const {
        auto now = chrono::system_clock::now();
        time_t now_time = chrono::system_clock::to_time_t(now);
        tm* now_tm = localtime(&now_time);
        
        stringstream ss;
        ss << put_time(now_tm, "%Y-%m-%d");
        return ss.str();
    }
    
    void setConsoleColor(int colorCode) const {
        cout << "\033[" << colorCode << "m";
    }
    
    void resetConsoleColor() const {
        cout << "\033[" << ConsoleColor::DEFAULT << "m";
    }
    
public:
    LuckDrawSystem() {
        unsigned seed = chrono::system_clock::now().time_since_epoch().count();
        rng = mt19937(seed);
        initDatabase();
        loadUserData();
    }
    
    DailyLuck drawLuck() {
        DailyLuck result;
        result.date = getCurrentDate();
        
        uniform_int_distribution<int> loveDist(0, db.love.size()-1);
        result.details["love"] = db.love[loveDist(rng)];
        
        uniform_int_distribution<int> careerDist(0, db.career.size()-1);
        result.details["career"] = db.career[careerDist(rng)];
        
        uniform_int_distribution<int> healthDist(0, db.health.size()-1);
        result.details["health"] = db.health[healthDist(rng)];
        
        uniform_int_distribution<int> wealthDist(0, db.wealth.size()-1);
        result.details["wealth"] = db.wealth[wealthDist(rng)];
        
        vector<string> types = {"大吉", "中吉", "小吉", "平", "凶"};
        vector<double> weights = {0.1, 0.2, 0.3, 0.3, 0.1};
        int typeIndex = weightedRandom(weights);
        result.overallType = types[typeIndex];
        result.overallDesc = generateOverallDesc(result.overallType);
        
        if (result.overallType == "大吉") {
            result.colorCode = ConsoleColor::RED;
        } else if (result.overallType == "中吉") {
            result.colorCode = ConsoleColor::YELLOW;
        } else if (result.overallType == "小吉") {
            result.colorCode = ConsoleColor::GREEN;
        } else if (result.overallType == "平") {
            result.colorCode = ConsoleColor::GRAY;
        } else {
            result.colorCode = ConsoleColor::BLACK;
        }
        
        user.history.insert(user.history.begin(), result);
        if (user.history.size() > 30) {
            user.history.pop_back();
        }
        user.lastDrawDate = getTodayDate();
        
        saveUserData();
        
        return result;
    }
    
    bool hasDrawnToday() const {
        return user.lastDrawDate == getTodayDate();
    }
    
    void displayLuck(const DailyLuck& luck) const {
        cout << "\n========== 今日运势 ==========\n";
        
        setConsoleColor(luck.colorCode);
        cout << "综合运势: " << luck.overallType << endl;
        resetConsoleColor();
        
        cout << "描述: " << luck.overallDesc << endl;
        cout << "时间: " << luck.date << endl;
        
        cout << "\n--------- 详细运势 ---------\n";
        cout << "爱情: " << luck.details.at("love") << endl;
        cout << "事业: " << luck.details.at("career") << endl;
        cout << "健康: " << luck.details.at("health") << endl;
        cout << "财运: " << luck.details.at("wealth") << endl;
        
        cout << "============================\n";
    }
    
    void displayHistory() const {
        if (user.history.empty()) {
            cout << "\n暂无历史记录\n";
            return;
        }
        
        cout << "\n======== 近期运势 ========\n";
        for (const auto& luck : user.history) {
            setConsoleColor(luck.colorCode);
            cout << luck.date << " - " << luck.overallType;
            resetConsoleColor();
            cout << endl;
        }
        cout << "=======================\n";
    }
    
    void saveUserData() {
        ofstream outFile("user_data.txt");
        if (!outFile) {
            cerr << "无法保存用户数据" << endl;
            return;
        }
        
        outFile << user.userId << endl;
        outFile << user.lastDrawDate << endl;
        outFile << user.history.size() << endl;
        
        for (const auto& luck : user.history) {
            outFile << luck.date << endl;
            outFile << luck.overallType << endl;
            outFile << luck.colorCode << endl;
            
            outFile << luck.details.at("love") << endl;
            outFile << luck.details.at("career") << endl;
            outFile << luck.details.at("health") << endl;
            outFile << luck.details.at("wealth") << endl;
        }
        
        outFile.close();
    }
    
    void loadUserData() {
        ifstream inFile("user_data.txt");
        if (!inFile) {
            user.userId = "user_" + to_string(rng());
            user.lastDrawDate = "";
            return;
        }
        
        getline(inFile, user.userId);
        getline(inFile, user.lastDrawDate);
        
        string line;
        getline(inFile, line);
        int historySize = stoi(line);
        
        for (int i = 0; i < historySize; ++i) {
            DailyLuck luck;
            
            getline(inFile, luck.date);
            getline(inFile, luck.overallType);
            
            getline(inFile, line);
            luck.colorCode = stoi(line);
            
            getline(inFile, line);
            luck.details["love"] = line;
            
            getline(inFile, line);
            luck.details["career"] = line;
            
            getline(inFile, line);
            luck.details["health"] = line;
            
            getline(inFile, line);
            luck.details["wealth"] = line;
            
            user.history.push_back(luck);
        }
        
        inFile.close();
    }
    
    string getUserId() const {
        return user.userId;
    }
};

void displayMenu() {
    cout << "\n======== 每日签运 ========\n";
    cout << "1. 抽签\n";
    cout << "2. 查看历史记录\n";
    cout << "3. 显示用户ID\n";
    cout << "4. 退出\n";
    cout << "=========================\n";
    cout << "请选择: ";
}

int main() {
	SetConsoleOutputCP(65001);
    SetConsoleCP(65001);
	
    LuckDrawSystem system;
    
    cout << "欢迎使用每日签运系统!" << endl;
    cout << "当前用户ID: " << system.getUserId() << endl;
    
    while (true) {
        displayMenu();
        
        int choice;
        cin >> choice;
        
        if (cin.fail()) {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "输入无效，请重新选择!" << endl;
            continue;
        }
        
        switch (choice) {
            case 1: {
                if (system.hasDrawnToday()) {
                    cout << "\n今天已经抽过签了，请明天再来!" << endl;
                } else {
                    DailyLuck luck = system.drawLuck();
                    system.displayLuck(luck);
                }
                break;
            }
            case 2:
                system.displayHistory();
                break;
            case 3:
                cout << "\n用户ID: " << system.getUserId() << endl;
                break;
            case 4:
                cout << "感谢使用，再见!" << endl;
                return 0;
            default:
                cout << "无效选择，请重新输入!" << endl;
        }
    }
    
    return 0;
}